package com.brotherly.util;

import java.util.LinkedList;

public class ReusablePool<Element>
{
    protected Factory<Element> factory;

    protected int maxCount = 1000;
    protected int freeCount = 1000;
    protected LinkedList<Element> cacheList = new LinkedList<Element>();

    public ReusablePool(int maxCount, Factory<Element> factory)
    {
        this.maxCount = maxCount;
        this.freeCount = maxCount;
        this.factory = factory;
    }

    public int getFreeCount()
    {
        return freeCount;
    }

    public int getCacheCount()
    {
        return cacheList.size();
    }

    synchronized public Element alloc()
    {
        Element element = null;

        if (cacheList.size() == 0 || this.freeCount > 0)
        {
            --this.freeCount;

            try
            {
                element = factory.newInstance();
            }
            catch (Exception e)
            {}
        } else
        {
            element = cacheList.removeFirst();
        }

        try
        {
            factory.init(element);
        }
        catch (Exception e)
        {}

        return element;
    }

    synchronized public void free(Element element)
    {
        try
        {
            factory.uninit(element);
        }
        catch (Exception e)
        {}

        if (cacheList.size() < maxCount)
        {
            cacheList.addFirst(element);
        }
    }
}
